#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

#include "bdb_ops.h"
#include "timer.h"
#include "mempool.h"

static void bdb_setting_init(S_BDB_SETTING * setting);
int main(void);

int main()
{
	int ret = 0;
	S_BDB_CB *bdb = NULL;
	S_BDB_SETTING setting;

	int j;
	int i = 1;
	char key[11];
	char value[65];

	FILE *fp;
	struct timeval start;
	struct timeval end;
	struct timeval result;

	DBT *key_dbt = NULL;
	DBT *value_dbt = NULL;
	DBT *value_dbt_get = NULL;

	bdb_setting_init(&setting);

	if ((fp = fopen("./result", "a+")) == NULL) {
		fprintf(stderr, "fopen error\n");
		return -1;
	}

	if ((bdb = bdb_init(&setting)) == NULL) {
		fprintf(fp, "bdb_init error\n");
		fclose(fp);
		return -1;
	}

	snprintf(key, 11, "test%06d", i);
	snprintf(value, 65, "testtesttest%052d", i);

	if ((key_dbt = bdb_form_ro_dbt(key, 11)) == NULL) {
		fprintf(fp, "bdb form key dbt error\n");
		ret = -1;
		goto out;
	}

	if ((value_dbt = bdb_form_ro_dbt(value, 65)) == NULL) {
		fprintf(fp, "bdb form value dbt error\n");
		ret = -1;
		goto out;
	}

	if ((value_dbt_get = bdb_form_wr_dbt(NULL, 65)) == NULL) {
		fprintf(fp, "bdb form value_wr dbt error\n");
		ret = -1;
		goto out;
	}

	for (j = 0; j < 100; j++) {

		srand(time(NULL));
		gettimeofday(&start, NULL);

		for (i = 0; i < 100; i++) {
			key[(rand() % 10)] =
			    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxuz0123456789"
			    [(rand() % 62)];
			if ((ret =
			     bdb_put(bdb, NULL, key_dbt, value_dbt, 0)) != 0) {
				fprintf(fp,
					"[%d] bdb put key-value error: %s\n", i,
					db_strerror(ret));
			}
		}

		gettimeofday(&end, NULL);
		DLIB_UTIMER_SUB(&end, &start, &result);

		fprintf(fp, "RESULT[%d]: 100000(10 + 64) puts cost %06fs\n",
			j, result.tv_sec + (float) result.tv_usec / 1000000);

	}

	if ((ret = bdb_get(bdb, NULL, key_dbt, value_dbt_get, 0)) != 0) {
		fprintf(fp, "bdb get key-value error: %s\n", db_strerror(ret));
	} else {
		fprintf(fp, "OUT: value is %s\n", (char *) value_dbt_get->data);
	}

#ifdef _DEBUG
	bdb_dump(fp, bdb);
#endif

out:
	fclose(fp);
	if (key_dbt != NULL)
		bdb_destroy_dbt(key_dbt);
	if (value_dbt != NULL)
		bdb_destroy_dbt(value_dbt);
	if (value_dbt_get != NULL)
		bdb_destroy_dbt(value_dbt_get);
	bdb_exit(bdb);

	return ret;
}

static void bdb_setting_init(S_BDB_SETTING * setting)
{
	setting->verbose = 0;

	setting->env_home = "/tmp/data/";
	setting->env_flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
	    DB_INIT_MPOOL | DB_INIT_TXN | DB_THREAD | DB_RECOVER;

	setting->db_type = DB_BTREE;
	setting->db_file = "default.db";
	setting->db_flags = DB_CREATE | DB_AUTO_COMMIT | DB_THREAD;
	setting->db_mode = 0664;

	setting->page_size = 4096;
	setting->cache_size = 0;
	setting->txn_lg_bsize = 32 * 1024;

	setting->txn_nosync = 0;
	setting->dldetect_val = 100 * 1000;
	setting->chkpoint_val = 60;

	return;
}
